﻿using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using VerifyDomainOutlookAddIn.Internal;

namespace VerifyDomainOutlookAddIn.Models
{
    class VerifyDomainService
    {
        /// <summary>
        /// ドメインを確認します。
        /// </summary>
        /// <param name="mail">メールアイテム。</param>
        /// <returns>送信を続けるかどうか。</returns>
        public bool VerifyDomain(MailItem mail)
        {
            var senderDomain = mail.GetSenderDomain();
            var recipientsAddresses = mail.GetRecipientsSmtpAddresses();

            var externalDomainAddresses = GetExternalDomainAddresses(senderDomain, recipientsAddresses);

            if (!externalDomainAddresses.Any())
            {
                return true;
            }

            var isContinue = Messenger.ConfirmContinueSend(
                "外部ドメインへのメールです。",
                Settings.Current.SendWaitMinutes,
                "外部ドメインの宛先",
                string.Join("; ", externalDomainAddresses));

            if (isContinue)
            {
                mail.SetSendWaitMinutes(Settings.Current.SendWaitMinutes);
            }

            return isContinue;
        }

        /// <summary>
        /// 外部ドメインのアドレスを取得します。
        /// </summary>
        /// <param name="internalDomain">内部ドメイン。</param>
        /// <param name="recipientsAddresses">受信者のアドレス。</param>
        /// <returns></returns>
        static List<string> GetExternalDomainAddresses(string internalDomain, IEnumerable<string> recipientsAddresses)
        {
            if (string.IsNullOrEmpty(internalDomain))
            {
                throw new ArgumentNullException("internalDomain");
            }
            if (recipientsAddresses == null)
            {
                throw new ArgumentNullException("recipientsAddresses");
            }

            var domainRegex = new Regex(string.Format(".*@{0}", internalDomain));

            return recipientsAddresses
                .Where(x => !domainRegex.IsMatch(x))
                .ToList();
        }

        /// <summary>
        /// エラーを処理します。
        /// </summary>
        /// <param name="ex">エラー。</param>
        /// <param name="mail">メールアイテム。</param>
        /// <returns>送信を続けるかどうか。</returns>
        public bool HandleError(System.Exception ex, MailItem mail)
        {
            var isContinue = Messenger.ConfirmContinueSend(
                "ドメインの確認処理でエラーが発生しました。",
                Settings.Current.SendWaitMinutes,
                "エラー",
                ex.Message + Environment.NewLine + ex.StackTrace);

            if (isContinue)
            {
                mail.SetSendWaitMinutes(Settings.Current.SendWaitMinutes);
            }

            return isContinue;
        }
    }
}
